/**
 * Description:
 * Class Name:ClassTest
 * Date:2022/4/30 12:03
 *
 * @author LTisme
 * @version JAVA17
 */
package 疯狂Java讲义.第18章_类加载机制与反射._18_3_通过反射查看信息._18_3_2_从Class中获取信息;

import java.lang.annotation.Annotation;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Arrays;

@Repeatable(Annos.class)
@interface Anno{}                       // 通过可重复注解修饰，该注解变得可重复

@Retention(RetentionPolicy.RUNTIME)
@interface Annos{                       // 这个是Anno的可重复注解的容器
    Anno[] value();
}

// 使用4个注解修饰该类
@SuppressWarnings(value = "unchecked")
@Deprecated
@Anno
@Anno
public class ClassTest {
    private ClassTest(){}
    public ClassTest(String name){
        System.out.println("执行有参数的构造器");
    }

    public void info(){
        System.out.println("执行无参数的info方法");
    }
    public void info(String str){
        System.out.println("执行有参数的info方法，其str参数值：" + str);
    }

    // 定义一个测试用的非静态内部类
    class Inner{}

    public static void main(String[] args) throws Exception{
        // 下面代码可以获取ClassTest对应的Class
        Class<ClassTest> clazz = ClassTest.class;
        // 获取该Class对象所对应类的全部构造器
        Constructor<?>[] constructors = clazz.getDeclaredConstructors();
        System.out.println("ClassTest类的全部构造器如下：");
        for (var c :
                constructors) {
            System.out.println(c);
        }

        // 获取该Class对象所对应类的全部public修饰的构造器
        Constructor<?>[] publicConstructors = clazz.getConstructors();
        System.out.println("ClassTest类的全部public修饰的构造器如下：");
        for (var c :
                publicConstructors) {
            System.out.println(c);
        }

        // 获取该Class对象所对应类的全部public 修饰的方法
        Method[] publicMethods = clazz.getMethods();
        System.out.println("ClassTest类的全部public修饰的方法如下：");
        for (var c :
                publicMethods) {
            System.out.println(c);
        }

        // 获取该Class对象所对应类的全部public 修饰的方法
        Method method = clazz.getMethod("info", String.class);
        System.out.println("ClassTest里带一个字符串参数的info方法：" + method);

        // 获取该Class对象所对应类的全部注解
        Annotation[] annotations = clazz.getAnnotations();
        System.out.println("ClassTest类的全部注解如下：");
        for (var c :
                annotations) {
            System.out.println(c);
        }
        // 获取对应类型的注解
        System.out.println("该Class元素上的@SuppressWarnings注解为：" + Arrays.toString(clazz.getAnnotationsByType(SuppressWarnings.class)));
        // 获取对应类型的注解
        System.out.println("该Class元素上的@Anno注解为：" + Arrays.toString(clazz.getAnnotationsByType(Anno.class)));

        // 获取该Class对象所对应的全部内部类
        Class<?>[] inners = clazz.getDeclaredClasses();
        System.out.println("ClassTest类的全部内部类如下：");
        for (var c :
                inners) {
            System.out.println(c);
        }

        // 使用Class.forName()方法加载ClassTest的Inner内部类
        Class<?> inClazz = Class.forName("疯狂Java讲义.第18章_类加载机制与反射._18_3_通过反射查看信息._18_3_2_从Class中获取信息.ClassTest$Inner");
        // 通过getDeclaringClass()访问该类所在的外部类
        System.out.println("inClazz对应类的外部类为：" + inClazz.getDeclaringClass());
        // 获取包名
        System.out.println("ClassTest的包名为：" + clazz.getPackageName());
        // 获取父类
        System.out.println("ClassTest的父类为：" + clazz.getSuperclass());
    }
}
//ClassTest类的全部构造器如下：
//private 疯狂Java讲义.第18章_类加载机制与反射._18_3_通过反射查看信息._18_3_2_从Class中获取信息.ClassTest()
//public 疯狂Java讲义.第18章_类加载机制与反射._18_3_通过反射查看信息._18_3_2_从Class中获取信息.ClassTest(java.lang.String)
//ClassTest类的全部public修饰的构造器如下：
//public 疯狂Java讲义.第18章_类加载机制与反射._18_3_通过反射查看信息._18_3_2_从Class中获取信息.ClassTest(java.lang.String)
//ClassTest类的全部public修饰的方法如下：
//public static void 疯狂Java讲义.第18章_类加载机制与反射._18_3_通过反射查看信息._18_3_2_从Class中获取信息.ClassTest.main(java.lang.String[]) throws java.lang.Exception
//public void 疯狂Java讲义.第18章_类加载机制与反射._18_3_通过反射查看信息._18_3_2_从Class中获取信息.ClassTest.info(java.lang.String)
//public void 疯狂Java讲义.第18章_类加载机制与反射._18_3_通过反射查看信息._18_3_2_从Class中获取信息.ClassTest.info()
//public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
//public final void java.lang.Object.wait() throws java.lang.InterruptedException
//public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
//public boolean java.lang.Object.equals(java.lang.Object)
//public java.lang.String java.lang.Object.toString()
//public native int java.lang.Object.hashCode()
//public final native java.lang.Class java.lang.Object.getClass()
//public final native void java.lang.Object.notify()
//public final native void java.lang.Object.notifyAll()
//ClassTest里带一个字符串参数的info方法：public void 疯狂Java讲义.第18章_类加载机制与反射._18_3_通过反射查看信息._18_3_2_从Class中获取信息.ClassTest.info(java.lang.String)
//ClassTest类的全部注解如下：
//@java.lang.Deprecated(forRemoval=false, since="")
//@疯狂Java讲义.第18章_类加载机制与反射._18_3_通过反射查看信息._18_3_2_从Class中获取信息.Annos({@疯狂Java讲义.第18章_类加载机制与反射._18_3_通过反射查看信息._18_3_2_从Class中获取信息.Anno(), @疯狂Java讲义.第18章_类加载机制与反射._18_3_通过反射查看信息._18_3_2_从Class中获取信息.Anno()})
//该Class元素上的@SuppressWarnings注解为：[]
//该Class元素上的@Anno注解为：[@疯狂Java讲义.第18章_类加载机制与反射._18_3_通过反射查看信息._18_3_2_从Class中获取信息.Anno(), @疯狂Java讲义.第18章_类加载机制与反射._18_3_通过反射查看信息._18_3_2_从Class中获取信息.Anno()]
//ClassTest类的全部内部类如下：
//class 疯狂Java讲义.第18章_类加载机制与反射._18_3_通过反射查看信息._18_3_2_从Class中获取信息.ClassTest$Inner
//inClazz对应类的外部类为：class 疯狂Java讲义.第18章_类加载机制与反射._18_3_通过反射查看信息._18_3_2_从Class中获取信息.ClassTest
//ClassTest的包名为：疯狂Java讲义.第18章_类加载机制与反射._18_3_通过反射查看信息._18_3_2_从Class中获取信息
//ClassTest的父类为：class java.lang.Object
